package com.wh.common.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.similarity.LongestCommonSubsequence;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GeodeticCurve;
import org.gavaghan.geodesy.GlobalCoordinates;

import java.math.BigDecimal;

/**
 * @author wenhao
 */
public class DistanceUtil {

    public static final double EPS = 1e-6;

    /**
     * 计算两个坐标距离，单位：M
     * @param latitudeA
     * @param longitudeA
     * @param latitudeB
     * @param longitudeB
     * @return
     */
    public static double calculateGeoForMeter(BigDecimal latitudeA, BigDecimal longitudeA ,BigDecimal latitudeB, BigDecimal longitudeB) {
        GlobalCoordinates pointA = new GlobalCoordinates(latitudeA.doubleValue(), longitudeA.doubleValue());
        GlobalCoordinates pointB = new GlobalCoordinates(latitudeB.doubleValue(), longitudeB.doubleValue());
        GeodeticCurve geoCurve = new GeodeticCalculator().calculateGeodeticCurve(Ellipsoid.Sphere, pointA, pointB);
        return geoCurve.getEllipsoidalDistance();
    }

    /**
     * 计算两个坐标距离，单位：KM
     * @param latitudeA
     * @param longitudeA
     * @param latitudeB
     * @param longitudeB
     * @return
     */
    public static double calculateGeoForKMeter(BigDecimal latitudeA, BigDecimal longitudeA , BigDecimal latitudeB, BigDecimal longitudeB) {
        return calculateGeoForMeter(latitudeA, longitudeA, latitudeB, longitudeB) / 1000;
    }

    /**
     * 计算LCS
     *
     * @param str1
     * @param str2
     * @return
     */
    public static int calculateLCSDistanceForStr(String str1, String str2) {
        if (StringUtils.isBlank(str1) && StringUtils.isBlank(str2)) {
            return 0;
        }
        if (StringUtils.isBlank(str1)) {
            return StringUtils.length(str2);
        }
        if (StringUtils.isBlank(str2)) {
            return StringUtils.length(str1);
        }
        LongestCommonSubsequence lcs = new LongestCommonSubsequence();
        return lcs.apply(str1, str2);
    }

    public static void main(String[] args) {
        System.out.println(calculateSimilarityFromEdit("曼店123", "开元酒店1"));
        System.out.println(calculateSimilarityFromEdit("曼店", "开元酒店1"));
    }

    /**
     * 计算两个字符串的相似度：[0, 1]
     *
     * @param str1
     * @param str2
     * @return
     */
    public static double calculateSimilarityFromEdit(String str1, String str2) {
        int maxLength = Math.max(StringUtils.length(str1), StringUtils.length(str2));
        if (maxLength <= 0) {
            return 1.0;
        }
        int lcsDistance = calculateLCSDistanceForStr(str1, str2);
        return 1.0 * lcsDistance / maxLength;
    }

}
